package com.feiyu.gen;

import com.feiyu.entity.BaseColumnInfo;
import com.feiyu.entity.BaseConfigInfo;
import com.feiyu.entity.BaseTableInfo;
import com.feiyu.mapper.CommonMapper;
import com.feiyu.util.FreeMarkerUtil;
import com.feiyu.util.MybatisUtils;
import com.feiyu.util.StringUtil;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author nanshouxiao@teacher.com.cn
 * @date 2018-08-27 15:29
 */
public class NewMainGen {
    private static final String daoTemplate = "daoTemplate.ftl";

    private static final String beanTemplate = "beanTemplate.ftl";

    /**
     * 查询时如果是自增主键，仍然会查主键
     */
    private static final String xmlTemplate = "xmlTemplate.ftl";

    private static final String serviceTemplate = "serviceTemplate.ftl";

    private static final String serviceImplTemplate = "serviceImplTemplate.ftl";

    private static final String controllerTemplate = "controllerTemplate.ftl";

    private static final String entitySubPackage = ".bean";
    private static final String mapperSubPackage = ".mapper";
    private static final String serviceSubPackage = ".service";
    private static final String serviceImplSubPackage = ".service.impl";
    private static final String controllerSubPackage = ".controller";

    public static void main(String[] args) throws IOException {
        generate();
    }

    public static void generate() {
        String tableSchema = "p_crawler";
        String tableName = "t_house_unit";
        BaseConfigInfo configInfo = new BaseConfigInfo();
        configInfo.setAuthor("feiyu127@gmail.com");
        configInfo.setPackageName("com.feiyu.house");
        configInfo.setMapperRemovePackage("com.feiyu.house");
        configInfo.setEntitySubPackage(entitySubPackage);
        configInfo.setMapperSubPackage(mapperSubPackage);
        configInfo.setServiceSubPackage(serviceSubPackage);
        configInfo.setServiceImplSubPackage(serviceImplSubPackage);
        configInfo.setControllerSubPackage(controllerSubPackage);
        configInfo.setIsMyBatisPlus(true);
        configInfo.setCommonMapperName("BaseMapper");
        configInfo.setCommonMapperPath("com.feiyu.common.base.BaseMapper");
        configInfo.setCommonServiceName("BaseService");
        configInfo.setCommonServicePath("com.feiyu.common.base.BaseService");
        configInfo.setCommonServiceImplName("BaseServiceImpl");
        configInfo.setCommonServiceImplPath("com.feiyu.common.base.BaseServiceImpl");
        configInfo.setCommonControllerName("BaseController");
        configInfo.setCommonControllerPath("com.feiyu.common.base.BaseController");
        configInfo.setTablePrefix("t_");
//        configInfo.setWorkspaceDir("E:\\spring_study\\project");
        configInfo.setWorkspaceDir("H:\\idea_workspace\\demo_project");
        configInfo.setProjectName("crawler");
        Map<String, Object> dataModel = getInfo(configInfo, tableSchema, tableName);
        generateFile("bean", dataModel);
        generateFile("dao", dataModel);
        generateFile("xml", dataModel);
        generateFile("service", dataModel);
        generateFile("serviceImpl", dataModel);
        generateFile("controller", dataModel);

    }

    public static Map<String, Object> getInfo(BaseConfigInfo configInfo, String tableSchema, String tableName) {
        SqlSessionFactory sqlSessionFactory = MybatisUtils.getSqlSessionFactory();
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            CommonMapper commonMapper = sqlSession.getMapper(CommonMapper.class);

            BaseTableInfo tableInfo = commonMapper.getTableInfo(tableSchema, tableName);
            if (tableInfo == null) {
                throw new RuntimeException("table " + tableSchema + "." + tableName + " is not exist;");
            }
            tableInfo.setClassName(StringUtil.getHumName(tableName.substring(configInfo.getTablePrefix().length()), true));
            List<BaseColumnInfo> columnInfoList = commonMapper.getColumnInfo(tableSchema, tableName);
            columnInfoList.stream().filter(BaseColumnInfo::getIsPrimaryKey).forEach(column -> {
                tableInfo.setPrimaryColumnName(column.getColumnName());
                tableInfo.setPrimaryJavaName(column.getColumnJavaName());
                tableInfo.setPrimaryJavaType(column.getJavaType());
                tableInfo.setPrimaryIsAutoIncrement(column.getIsAutoIncrement());
            });
            Map<String, Object> objectMap = new HashMap<>();
            objectMap.put("table", tableInfo);
            objectMap.put("columnList", columnInfoList);
            objectMap.put("config", configInfo);
            return objectMap;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    private static void generateFile(String type, Map<String, Object> dataModel) {
        BaseConfigInfo configInfo = (BaseConfigInfo) dataModel.get("config");
        BaseTableInfo tableInfo = (BaseTableInfo) dataModel.get("table");
        String templateName = null;
        String filePath = null;
        String projectPath = configInfo.getWorkspaceDir() + File.separator + configInfo.getProjectName();
        String xmlFileDir = configInfo.getMybatisXMLFileDir();
        if (xmlFileDir == null) {
            xmlFileDir = projectPath + "/src/main/resources/mapper/";
        }
        String beanClassName = tableInfo.getClassName();
        String mapperLocationRemovePackage = configInfo.getMapperRemovePackage();
        String packageName = configInfo.getPackageName();
        String xmlPackagePath = packageName.replace(mapperLocationRemovePackage, "").replace(".", File.separator) + "/";
        switch (type) {
            case "bean":
                templateName = beanTemplate;
                filePath = getFileSavePath(configInfo, type) + beanClassName + ".java";
                break;
            case "dao":
                filePath = getFileSavePath(configInfo, type) + beanClassName + "Mapper.java";
                templateName = daoTemplate;
                break;
            case "xml":
                filePath = xmlFileDir + xmlPackagePath + beanClassName.substring(0, 1).toLowerCase()
                        + beanClassName.substring(1) + "Mapper.xml";
                templateName = xmlTemplate;
                break;
            case "service":
                filePath = getFileSavePath(configInfo, type) + beanClassName + "Service.java";
                templateName = serviceTemplate;
                break;
            case "serviceImpl":
                filePath = getFileSavePath(configInfo, type) + beanClassName + "ServiceImpl.java";
                templateName = serviceImplTemplate;
                break;
            case "controller":
                filePath = getFileSavePath(configInfo, type) + beanClassName + "Controller.java";
                templateName = controllerTemplate;
                break;
            default:
                break;
        }
        FreeMarkerUtil.processFile(templateName, dataModel, filePath);
//        FreeMarkerUtil.processConsole(templateName, dataModel);
        System.out.println("成功创建文件:" + filePath);
    }

    private static String getFileSavePath(BaseConfigInfo configInfo, String type) {
        String subPackage = null;
        switch (type) {
            case "bean":
                subPackage = configInfo.getEntitySubPackage();
                break;
            case "dao":
                subPackage = configInfo.getMapperSubPackage();
                break;
            case "service":
                subPackage = configInfo.getServiceSubPackage();
                break;
            case "serviceImpl":
                subPackage = configInfo.getServiceImplSubPackage();
                break;
            case "controller":
                subPackage = configInfo.getControllerSubPackage();
                break;
            default:
                break;
        }
        String javaFileDir = configInfo.getJavaFileDir();
        String projectPath = configInfo.getWorkspaceDir() + File.separator + configInfo.getProjectName();
        if (javaFileDir == null) {
            javaFileDir = projectPath + "/src/main/java/";
        }
        String packageName = configInfo.getPackageName();
        String packagePath = packageName.replace(".", File.separator);
        return javaFileDir + packagePath + subPackage.replace(".", File.separator) + File.separator;
    }
}
